package solutions.ferpa.ztest.intf;

import br.com.telescope.adsrt.dom.DomEMail;
import br.com.telescope.adsrt.dom.DomFlag;
import br.com.telescope.adsrt.dom.DomId;
import br.com.telescope.adsrt.dom.DomInteger;
import br.com.telescope.adsrt.dom.DomLogin;
import br.com.telescope.adsrt.dom.DomLower;
import br.com.telescope.adsrt.dom.DomUpper;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.sql.ModelQuery;
import br.com.telescope.t2.EntityBinding;
import br.com.telescope.t2.ServiceModel;
import br.com.telescope.t2.exception.ApplicationRuntimeException;
import br.com.telescope.t2.exception.Severity;
import br.com.telescope.t2.feature.DeleteFeature;
import br.com.telescope.t2.feature.InsertFeature;
import br.com.telescope.t2.feature.ListFeature;
import br.com.telescope.t2.feature.QueryFeature;
import br.com.telescope.t2.feature.UpdateFeature;
import br.com.telescope.t2.feature.ViewFeature;
import br.com.telescope.util.HashUtil;
import br.com.telescope.util.ObjectUtil;
import solutions.ferpa.ztest.ent.*;

/**
 * Colaboradores (pessoa x usuário do sistema).
 * <p>
 * Interface para manutenção de Operadores (funcionários, colaboradores).
 * <P>
 * Telescope origin: ZTEST.CAD_COLABORADORES
 * <P>
 * Base entity: ZTEST.PESSOA
 * <P>
 * @author TELESCOPE - Build task T2 Web Interface Generator
 * <P>
 * @version 0.1
 */
public class CadColaboradores extends ServiceModel {
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    public static final String GLOBAL_NAME = "ZTEST.CAD_COLABORADORES";
    
    @Override
    public String globalName() {
        return GLOBAL_NAME;
    }
    
    {
        setTitle("Colaboradores (pessoa x usuário do sistema)");
    }
    
    protected EntPessoa base;
    protected EntTipoPessoa tpes;
    protected EntUsuarios usua;
    protected EntPessoa rec; // NEED_TJW1_COMPATIBILITY
    
    // Record items
    private DomUpper aNomeApresentacao;
    private DomUpper aNome;
    private DomUpper aSobrenome;
    private DomUpper aCodigo;
    private DomInteger aCodigoNumerico;
    private DomEMail aEMail;
    private DomFlag aAtivo;
    private DomId aTipoPessoaId;
    private DomId aId;
    private DomId aUsuarioAssociadoId;
    private DomUpper aTpesNome;
    private DomLogin aUsuaLogin;
    private DomLower aLoginUsuario;
    
    // Query items
    private DomInteger qCodigoNumerico;
    private DomFlag qAtivo;
    private DomUpper qCodigo;
    private DomLogin qUsuaLogin;
    private DomUpper qSobrenome;
    private DomUpper qNomeApresentacao;
    private DomUpper qTpesNome;
    private DomEMail qEMail;
    private DomUpper qNome;
    
    @Override
    public String getBaseSql() {
        return "select BASE.*"
                + " , TPES.NOME as TPES_NOME"
                + " , USUA.LOGIN as USUA_LOGIN"
                + " , TPES.ID as Z_TPES_ID"
                + " , USUA.ID as Z_USUA_ID"
                + " from PESSOA BASE"
                + " join TIPO_PESSOA TPES on TPES.ID = BASE.TIPO_PESSOA_ID"
                + " left join USUARIOS USUA on USUA.ID = BASE.USUARIO_ASSOCIADO_ID";
    }
    
    @Override
    public String getBaseSqlWhereClause() {
        
        return " where base.usuario_associado_id is not null";
    }
    
    @Override
    public void initAttributes() {
        
        aNomeApresentacao = new DomUpper();
        aNomeApresentacao.context(ctx).name("NOME_APRESENTACAO").label("Nome completo da pessoa");
        
        aNome = new DomUpper();
        aNome.context(ctx).name("NOME").label("Nome da pessoa");
        
        aSobrenome = new DomUpper();
        aSobrenome.context(ctx).name("SOBRENOME").label("Sobrenome da pessoa");
        
        aCodigo = new DomUpper();
        aCodigo.context(ctx).name("CODIGO").label("Código da pessoa");
        
        aCodigoNumerico = new DomInteger();
        aCodigoNumerico.context(ctx).name("CODIGO_NUMERICO").label("Código numérico da pessoa");
        
        aEMail = new DomEMail();
        aEMail.context(ctx).name("E_MAIL").label("Email da pessoa");
        
        aAtivo = new DomFlag();
        aAtivo.context(ctx).name("ATIVO").label("Ativo (pessoa ok)");
        aAtivo.setDefaultValue("S");
        
        aTipoPessoaId = new DomId();
        aTipoPessoaId.context(ctx).name("TIPO_PESSOA_ID").label("Tipo da pessoa");
        
        aId = new DomId();
        aId.context(ctx).name("ID").label("Id");
        
        aUsuarioAssociadoId = new DomId();
        aUsuarioAssociadoId.context(ctx).name("USUARIO_ASSOCIADO_ID").label("Usuário associado");
        
        aTpesNome = new DomUpper();
        aTpesNome.context(ctx).name("TPES_NOME").label("Sigla para o tipo da pessoa");
        aTpesNome.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(SELECT NOME as valor"
                + " , NOME as pesquisar"
                + " , NOME as descricao"
                + " from TIPO_PESSOA TPES"
                + " where tpes.nome = 'USUÁRIO')", "q"));
        aTpesNome.setAutocompleteLength(0);
        aTpesNome.setDefaultValue("USUÁRIO");
        
        aUsuaLogin = new DomLogin();
        aUsuaLogin.context(ctx).name("USUA_LOGIN").label("Usuário do sistema");
        aUsuaLogin.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(SELECT LOGIN as valor"
                + " , LOGIN as pesquisar"
                + " , LOGIN as descricao"
                + " from USUARIOS USUA"
                + " where usua.ativo = 'S')", "q"));
        aUsuaLogin.setAutocompleteLength(1);
        
        aLoginUsuario = new DomLower();
        aLoginUsuario.context(ctx).name("LOGIN_USUARIO").label("Usuário do sistema").unbound(true);
        aLoginUsuario.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(select usua.login as valor"
                + "    ,usua.login as descricao"
                + "    ,usua.login || case when usua.nome_completo is null then '' else usua.nome_completo end as pesquisar"
                + " from usuarios usua"
                + " order by usua.login)", "q"));
        
        
        qCodigoNumerico = new DomInteger();
        qCodigoNumerico.context(ctx).name("CODIGO_NUMERICO").label("Código numérico da pessoa");
        
        qAtivo = new DomFlag();
        qAtivo.context(ctx).name("ATIVO").label("Ativo (pessoa ok)");
        
        qCodigo = new DomUpper();
        qCodigo.context(ctx).name("CODIGO").label("Código da pessoa");
        
        qUsuaLogin = new DomLogin();
        qUsuaLogin.context(ctx).name("USUA_LOGIN").label("Usuário do sistema");
        qUsuaLogin.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(SELECT LOGIN as valor"
                + " , LOGIN as pesquisar"
                + " , LOGIN as descricao"
                + " from USUARIOS USUA"
                + " where usua.ativo = 'S')", "q"));
        qUsuaLogin.setAutocompleteLength(1);
        
        qSobrenome = new DomUpper();
        qSobrenome.context(ctx).name("SOBRENOME").label("Sobrenome da pessoa");
        
        qNomeApresentacao = new DomUpper();
        qNomeApresentacao.context(ctx).name("NOME_APRESENTACAO").label("Nome completo da pessoa");
        
        qTpesNome = new DomUpper();
        qTpesNome.context(ctx).name("TPES_NOME").label("Sigla para o tipo da pessoa");
        qTpesNome.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(SELECT NOME as valor"
                + " , NOME as pesquisar"
                + " , NOME as descricao"
                + " from TIPO_PESSOA TPES"
                + " where tpes.nome = 'USUÁRIO')", "q"));
        qTpesNome.setAutocompleteLength(0);
        
        qEMail = new DomEMail();
        qEMail.context(ctx).name("E_MAIL").label("Email da pessoa");
        
        qNome = new DomUpper();
        qNome.context(ctx).name("NOME").label("Nome da pessoa");
    }
    
    @Override
    public void initEntityBindings() {
        EntityBinding binding;
        
        binding = new EntityBinding("ZTEST.TIPO_PESSOA", "TPES", "Z_TPES_ID", "ZTEST.CAD_TIPO_PESSOA.VIEW");
        binding.addFields(aTpesNome);
        entityBindings.add(binding);
    }
    
    @Override
    public String getQueryPkColumn() {
        return "BASE.ID";
    }
    
    @Override
    public void setId(String value) {
        this.aId.setValue(value);
    }
    
    @Override
    public EntPessoa getRecord() {
        if (base == null) {
            base = new EntPessoa(ctx);
            rec = base;
        }
        return this.base;
    }
    
    @Override
    public String getContextName() {
        return aNomeApresentacao.toText();
    }
    
    @Override
    public String getDefaultOrderBy() {
        return "NOME_APRESENTACAO, USUA_LOGIN, CODIGO_NUMERICO, ATIVO";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="QUERY">
    public class FQuery extends QueryFeature {
        
        @Override
        public void initForm() {
            addField(qNomeApresentacao, "opt");
            addField(qNome, "opt");
            addField(qSobrenome, "opt");
            addField(qUsuaLogin, "opt");
            addField(qCodigo, "opt");
            addField(qCodigoNumerico, "opt");
            addField(qEMail, "opt");
            addField(qAtivo, "opt");
            addField(qTpesNome, "opt");
        }
        
        {
            setFeatureName("QUERY");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="LIST">
    public class FList extends ListFeature {
        
        @Override
        public void initForm() {
            addField(aNomeApresentacao, "view");
            addField(aUsuaLogin, "view");
            addField(aCodigoNumerico, "view");
            addField(aAtivo, "view");
            addField(aTpesNome, "view");
        }
        
        {
            setFeatureName("LIST");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="VIEW">
    public class FView extends ViewFeature {
        
        @Override
        public void initForm() {
            addField(aNomeApresentacao, "view");
            addField(aNome, "view");
            addField(aSobrenome, "view");
            addField(aUsuaLogin, "view");
            addField(aCodigo, "view");
            addField(aCodigoNumerico, "view");
            addField(aEMail, "view");
            addField(aAtivo, "view");
            addField(aTpesNome, "view");
        }
        
        {
            setFeatureName("VIEW");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="INSERT">
    public class FInsert extends InsertFeature {
        
        @Override
        public void initForm() {
            aNome.setOptional(false);
            addField(aNome, "rqd");
            aSobrenome.setOptional(false);
            addField(aSobrenome, "rqd");
            aLoginUsuario.setOptional(false);
            addField(aLoginUsuario, "rqd");
            aCodigo.setOptional(false);
            addField(aCodigo, "rqd");
            addField(aCodigoNumerico, "opt");
            addField(aEMail, "opt");
            aTpesNome.setHidden(true);
            addField(aTpesNome, "hidden");
            aTipoPessoaId.setHidden(true);
            addField(aTipoPessoaId, "hidden");
            aId.setHidden(true);
            addField(aId, "hidden");
        }
        
        @Override
        public void preInsert() {
            try {
                criarNovoUsuario();
                traduzirFks();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("INSERT");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="UPDATE">
    public class FUpdate extends UpdateFeature {
        
        @Override
        public void initForm() {
            aNomeApresentacao.setEditable(false);
            addField(aNomeApresentacao, "view");
            aNome.setOptional(false);
            addField(aNome, "rqd");
            aSobrenome.setOptional(false);
            addField(aSobrenome, "rqd");
            aUsuaLogin.setEditable(false);
            addField(aUsuaLogin, "view");
            aCodigo.setOptional(false);
            addField(aCodigo, "rqd");
            addField(aCodigoNumerico, "opt");
            addField(aEMail, "opt");
            aAtivo.setOptional(false);
            addField(aAtivo, "rqd");
            aTpesNome.setEditable(false);
            addField(aTpesNome, "view");
            aTipoPessoaId.setHidden(true);
            addField(aTipoPessoaId, "hidden");
            aId.setHidden(true);
            addField(aId, "hidden");
        }
        
        @Override
        public void preDisplay() {
            try {
                prencherDadosUsuario();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("UPDATE");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DELETE">
    public class FDelete extends DeleteFeature {
        
        @Override
        public void initForm() {
            addField(aNomeApresentacao, "view");
            addField(aNome, "view");
            addField(aSobrenome, "view");
            addField(aUsuaLogin, "view");
            addField(aTpesNome, "view");
        }
        
        {
            setFeatureName("DELETE");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="initFeatures">
    
    @Override
    protected void initFeatures() {
        addFeature(new FQuery());
        addFeature(new FList());
        addFeature(new FView());
        addFeature(new FInsert());
        addFeature(new FUpdate());
        addFeature(new FDelete());
        super.initFeatures();
    }
    
    @Override
    public String getDefaultFeature() {
        return "QUERY";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">
    
    public String getNomeApresentacao() {
        return aNomeApresentacao.getValue();
    }
    
    public void setNomeApresentacao(String value) {
        this.aNomeApresentacao.setValue(value);
    }
    
    public String getNome() {
        return aNome.getValue();
    }
    
    public void setNome(String value) {
        this.aNome.setValue(value);
    }
    
    public String getSobrenome() {
        return aSobrenome.getValue();
    }
    
    public void setSobrenome(String value) {
        this.aSobrenome.setValue(value);
    }
    
    public String getCodigo() {
        return aCodigo.getValue();
    }
    
    public void setCodigo(String value) {
        this.aCodigo.setValue(value);
    }
    
    public Integer getCodigoNumerico() {
        return aCodigoNumerico.getValue();
    }
    
    public void setCodigoNumerico(Integer value) {
        this.aCodigoNumerico.setValue(value);
    }
    
    public String getEMail() {
        return aEMail.getValue();
    }
    
    public void setEMail(String value) {
        this.aEMail.setValue(value);
    }
    
    public String getAtivo() {
        return aAtivo.getValue();
    }
    
    public void setAtivo(String value) {
        this.aAtivo.setValue(value);
    }
    
    public Long getTipoPessoaId() {
        return aTipoPessoaId.getValue();
    }
    
    public void setTipoPessoaId(Long value) {
        this.aTipoPessoaId.setValue(value);
    }
    
    @Override
    public Long getId() {
        return aId.getValue();
    }
    
    public void setId(Long value) {
        this.aId.setValue(value);
    }
    
    public Long getUsuarioAssociadoId() {
        return aUsuarioAssociadoId.getValue();
    }
    
    public void setUsuarioAssociadoId(Long value) {
        this.aUsuarioAssociadoId.setValue(value);
    }
    
    public String getTpesNome() {
        return aTpesNome.getValue();
    }
    
    public void setTpesNome(String value) {
        this.aTpesNome.setValue(value);
    }
    
    public String getUsuaLogin() {
        return aUsuaLogin.getValue();
    }
    
    public void setUsuaLogin(String value) {
        this.aUsuaLogin.setValue(value);
    }
    
    public String getLoginUsuario() {
        return aLoginUsuario.getValue();
    }
    
    public void setLoginUsuario(String value) {
        this.aLoginUsuario.setValue(value);
    }
    public String getQueryNomeApresentacao() {
        return qNomeApresentacao.getQueryValue();
    }
    
    public void setQueryNomeApresentacao(String value) {
        this.qNomeApresentacao.setQueryValue(value);
    }
    public String getQueryNome() {
        return qNome.getQueryValue();
    }
    
    public void setQueryNome(String value) {
        this.qNome.setQueryValue(value);
    }
    public String getQuerySobrenome() {
        return qSobrenome.getQueryValue();
    }
    
    public void setQuerySobrenome(String value) {
        this.qSobrenome.setQueryValue(value);
    }
    public String getQueryUsuaLogin() {
        return qUsuaLogin.getQueryValue();
    }
    
    public void setQueryUsuaLogin(String value) {
        this.qUsuaLogin.setQueryValue(value);
    }
    public String getQueryCodigo() {
        return qCodigo.getQueryValue();
    }
    
    public void setQueryCodigo(String value) {
        this.qCodigo.setQueryValue(value);
    }
    public String getQueryCodigoNumerico() {
        return qCodigoNumerico.getQueryValue();
    }
    
    public void setQueryCodigoNumerico(String value) {
        this.qCodigoNumerico.setQueryValue(value);
    }
    public String getQueryEMail() {
        return qEMail.getQueryValue();
    }
    
    public void setQueryEMail(String value) {
        this.qEMail.setQueryValue(value);
    }
    public String getQueryAtivo() {
        return qAtivo.getQueryValue();
    }
    
    public void setQueryAtivo(String value) {
        this.qAtivo.setQueryValue(value);
    }
    public String getQueryTpesNome() {
        return qTpesNome.getQueryValue();
    }
    
    public void setQueryTpesNome(String value) {
        this.qTpesNome.setQueryValue(value);
    }
    // </editor-fold>
    
    /**
     * Criar novo usuário.
     * <p>
     * Antes de incluir/alterar uma pessoa:
     * <P>
     * * inserir um novo usuário
     * <P>
     * * atribuir novo usuário ao "usuario_associado_id"
     */
    private void criarNovoUsuario() throws AdsException {
        // <user-code id="20303907" parentId="20303891" hashcode="-70d9ecb6" length="864">
        // import br.com.telescope.t2.exception.Severity;
        // import br.com.telescope.util.HashUtil;
        
        EntUsuarios usuario = null;
        try {
            usuario = new EntUsuarios(ctx);
            usuario.findByLogin(aLoginUsuario.getValue());
        } catch (RecordNotFoundException e) {
            usuario.setNomeCompleto(aNome.getValue() + " " + aSobrenome.getValue());
            if (aEMail.isNotNull()) {
                usuario.setEMail(aEMail.getValue());
            }
            usuario.setLogin(aLoginUsuario.getValue());
            usuario.setSenhaHash(HashUtil.getSha1(aLoginUsuario.getValue()));
            usuario.ins();
        
            ctx.pushError(GLOBAL_NAME + ".USUARIO_CRIADO",
                    Severity.WARNING,
                    "Usuário do sistema criado! A senha registrada é igual ao nome do usuário e deverá ser trocada!");
        } finally {
            usuario.close();
        }
        getRecord().setUsuarioAssociadoId(usuario.valueOfId().longValue());
        // </user-code>
    }
    
    /**
     * Prencher dados do usuário.
     */
    private void prencherDadosUsuario() throws AdsException {
        // <user-code id="20392279" parentId="20392265" hashcode="-2cd30553" length="1326">
        EntUsuarios usuario = getRecord().findUsuarioAssociado();
        
        if (!usuario.valueOfNomeCompleto()
            .equals(getRecord().valueOfNome() + " " + getRecord().getSobrenome())) 
        {
            ctx.pushError(GLOBAL_NAME + ".NOME_PESSOA_DIFERENTE_USUARIO",
                    Severity.WARNING,
                    "O nome cadastrado para o usuário " + usuario.valueOfLogin() + " está diferente do nome desta pessoa"
                    + " (nome do usuário: " + usuario.valueOfNomeCompleto() + ")!");
        }    
        
        if (!usuario.getEMail().isNotNull() && getRecord().getEMail().isNotNull()) {
            if (!usuario.valueOfEMail().equals(getRecord().valueOfEMail())) { 
                ctx.pushError(GLOBAL_NAME + ".EMAIL_PESSOA_DIFERENTE_USUARIO",
                        Severity.WARNING,
                        "O email  cadastrado para o usuário " + usuario.valueOfLogin() + " está diferente do email desta pessoa"
                        + " (email do usuário: " + usuario.valueOfEMail() + ")!");
            }    
        }
                
        if (!usuario.valueOfAtivo().equals(getRecord().valueOfAtivo())) {
            ctx.pushError(GLOBAL_NAME + ".SITUACAO_PESSOA_DIFERENTE_USUARIO",
                    Severity.WARNING,
                    "A situação do atual do usuário " + usuario.valueOfLogin() + " está diferente da situação desta pessoa"
                    + " (situação do usuário: " + usuario.valueOfEMail() + ")!");
        }        
        // </user-code>
    }
    
    /**
     * Traduzir fks.
     */
    private void traduzirFks() throws AdsException {
        // <user-code id="20730647" parentId="20730635" hashcode="-43c35a07" length="498">
        // import br.com.telescope.sql.ModelQuery;
        // import br.com.telescope.util.ObjectUtil;
        
        try {
            if (getForm().hasFields("TPES_NOME")) {
                ModelQuery query = createQuery()
                        .select("TIPS.ID")
                        .from("TIPO_PESSOA", "TIPS")
                        .filter("TIPS.NOME", getForm().get("TPES_NOME"))
                        ;
                base.setTipoPessoaId(ObjectUtil.toLong(translateFk(query)));
            }
        } catch (AdsException ex) {
            throw new RuntimeException(ex);
        }
        
        // </user-code>
    }
}
